﻿using System.Configuration;

namespace FlitBit.Cache.Config
{
	/// <summary>
	///   Configuration section for cache settings.
	/// </summary>
	public class CacheConfigSection : ConfigurationSection
	{
		/// <summary>
		///   Default value determining whether to listen for network evictions.
		/// </summary>
		public const bool CDefaultListenForNetworkEvictions = true;

		/// <summary>
		///   Default value for max concurrent eviction workers if not set in config.
		/// </summary>
		public const int CDefaultMaxEvictionWorker = 4;

		/// <summary>
		///   Property name for cache net interfaces.
		/// </summary>
		public const string PropertyNameCacheNetInterfaces = "cacheNetInterfaces";

		/// <summary>
		///   Property name for listen-for network evictions.
		/// </summary>
		public const string PropertyNameListenForNetworkEvictions = "listenForNetworkEvictions";

		/// <summary>
		///   Property name for max concurrent eviction workers.
		/// </summary>
		public const string PropertyNameMaxEvictionWorkers = "maxEvictionWorkers";

		/// <summary>
		///   Property name for named caches.
		/// </summary>
		public const string PropertyNameNamedCaches = "namedCaches";

		/// <summary>
		///   Configuration section name for cache settings
		/// </summary>
		public static readonly string SectionName = "flitbit.cache";

		/// <summary>
		///   Indicates the maximum number of concurrent eviction workers the eviction manager
		///   should schedule.
		/// </summary>
		[ConfigurationProperty(PropertyNameMaxEvictionWorkers, DefaultValue = CDefaultMaxEvictionWorker)]
		public int MaxEvictionWorkers { get { return (int) this[PropertyNameMaxEvictionWorkers]; } set { this[PropertyNameMaxEvictionWorkers] = value; } }

		/// <summary>
		///   Configurations for named caches.
		/// </summary>
		[ConfigurationProperty(PropertyNameNamedCaches, IsDefaultCollection = true)]
		public NamedCacheConfigElementCollection NamedCaches { get { return (NamedCacheConfigElementCollection) this[PropertyNameNamedCaches]; } }

		/// <summary>
		///   Gets either the named set of options or the default options if named options don't exist.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="name"></param>
		/// <returns></returns>
		public MruCacheOptions NamedOrDefaultOptions<T>(string name)
		{
			var cfg = NamedCaches[name];
			if (cfg != null)
			{
				return cfg.ToOptions<T>();
			}
			return new NamedCacheConfigElement().ToOptions<T>();
		}

		/// <summary>
		///   Gets the current configuration section.
		/// </summary>
		public static CacheConfigSection Current
		{
			get
			{
				var config = ConfigurationManager.GetSection(
																										 SectionName) as CacheConfigSection;
				return config ?? new CacheConfigSection();
			}
		}
	}
}